﻿//------------------------------------------------------------------------------
// Copyright © FRA & FV 2014
// All rights reserved
//------------------------------------------------------------------------------
// Binary Serialization SDK
//
// SVN revision information:
//   $Revision: 97 $
//------------------------------------------------------------------------------
using System;
using System.IO;
using System.Text;

namespace FRAFV.Binary.Serialization
{
	/// <summary>Writes primitive types in binary to a stream with specific byte order and
	///   supports writing null-terminated strings in a specific encoding.</summary>
	public class BinStringWriter : BinWriter
	{
		private Encoding encoding;

		/// <summary>Initializes a new instance of the <see cref="T:FRAFV.Binary.Serialization.BinStringWriter" /> class
		///   based on the supplied stream and using <see cref="T:System.Text.UTF8Encoding" />.</summary>
		/// <param name="output">The output stream.</param>
		/// <exception cref="T:System.ArgumentException">The stream does not support writing, or the stream is already closed. </exception>
		/// <exception cref="T:System.ArgumentNullException">
		///   <paramref name="output" /> is null. </exception>
		public BinStringWriter(Stream output)
			: base(output, Encoding.UTF8)
		{
			this.encoding = Encoding.UTF8;
		}

		/// <summary>Initializes a new instance of the <see cref="T:FRAFV.Binary.Serialization.BinStringWriter" /> class
		///   based on the supplied stream and a specific character encoding.</summary>
		/// <param name="output">The output stream.</param>
		/// <param name="encoding">The character encoding. </param>
		/// <exception cref="T:System.ArgumentException">The stream does not support writing, or the stream is already closed. </exception>
		/// <exception cref="T:System.ArgumentNullException">
		///   <paramref name="output" /> or <paramref name="encoding" /> is null. </exception>
		public BinStringWriter(Stream output, Encoding encoding)
			: base(output, encoding)
		{
			this.encoding = encoding;
		}

		/// <summary>Initializes a new instance of the <see cref="T:FRAFV.Binary.Serialization.BinStringWriter" /> class
		///   based on the supplied stream with specific byte order and using <see cref="T:System.Text.UTF8Encoding" />.</summary>
		/// <param name="output">The output stream.</param>
		/// <param name="littleEndian">true to use the little-endian byte order (most significant byte first), or false
		///   to use the big-endian byte order (least significant byte first).</param>
		/// <exception cref="T:System.ArgumentException">The stream does not support writing, or the stream is already closed. </exception>
		/// <exception cref="T:System.ArgumentNullException">
		///   <paramref name="output" /> is null. </exception>
		public BinStringWriter(Stream output, bool littleEndian)
			: base(output, Encoding.UTF8, littleEndian)
		{
			this.encoding = Encoding.UTF8;
		}

		/// <summary>Initializes a new instance of the <see cref="T:FRAFV.Binary.Serialization.BinStringWriter" /> class
		///   based on the supplied stream with specific byte order and a specific character encoding.</summary>
		/// <param name="output">The output stream.</param>
		/// <param name="encoding">The character encoding. </param>
		/// <param name="littleEndian">true to use the little-endian byte order (most significant byte first), or false
		///   to use the big-endian byte order (least significant byte first).</param>
		/// <exception cref="T:System.ArgumentException">The stream does not support writing, or the stream is already closed. </exception>
		/// <exception cref="T:System.ArgumentNullException">
		///   <paramref name="output" /> or <paramref name="encoding" /> is null. </exception>
		public BinStringWriter(Stream output, Encoding encoding, bool littleEndian)
			: base(output, encoding, littleEndian)
		{
			this.encoding = encoding;
		}

		/// <summary>Writes a null-terminated string to this stream in the current encoding of the <see cref="T:FRAFV.Binary.Serialization.BinStringWriter" />,
		///   and advances the current position of the stream in accordance with the encoding used and the specific
		///   characters being written to the stream.</summary>
		/// <param name="value">The value to write. </param>
		/// <exception cref="T:System.IO.IOException">An I/O error occurs. </exception>
		/// <exception cref="T:System.ArgumentNullException">
		///   <paramref name="value" /> is null. </exception>
		/// <exception cref="T:System.ObjectDisposedException">The stream is closed. </exception>
		public override void Write(string value)
		{
			if (value == null)
				throw new ArgumentNullException("value");
			var data = encoding.GetBytes(value);
			OutStream.Write(data, 0, data.Length);
			base.Write('\0');
		}
	}
}
